#!/bin/bash
# -*- coding: utf-8 -*-
# CentOS 8 Python彩票爬虫一键安装脚本
# 可使用root用户运行
# 
# 功能：
# 1. 安装Python 3.8+
# 2. 安装MySQL 8.0
# 3. 安装Redis
# 4. 安装Python依赖包
# 5. 配置数据库
# 6. 设置系统服务
# 7. 配置防火墙
#
# 使用方法：
# chmod +x centos8_install.sh
# ./centos8_install.sh

set -e  # 遇到错误立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_step() {
    echo -e "${BLUE}[STEP]${NC} $1"
}

# 检查是否为root用户
check_root() {
    if [[ $EUID -ne 0 ]]; then
        log_error "此脚本需要root权限运行"
        exit 1
    fi
}

# 检查CentOS版本
check_centos_version() {
    if [[ ! -f /etc/centos-release ]]; then
        log_error "此脚本仅支持CentOS系统"
        exit 1
    fi
    
    local version=$(cat /etc/centos-release | grep -oE '[0-9]+' | head -1)
    if [[ $version -ne 8 ]]; then
        log_warn "此脚本专为CentOS 8设计，当前版本：CentOS $version"
        read -p "是否继续安装？(y/N): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            exit 1
        fi
    fi
}

# 更新系统
update_system() {
    log_step "更新系统包..."
    dnf update -y
    dnf install -y epel-release
    log_info "系统更新完成"
}

# 安装基础工具
install_basic_tools() {
    log_step "安装基础工具..."
    dnf install -y \
        wget \
        curl \
        vim \
        git \
        gcc \
        gcc-c++ \
        make \
        openssl-devel \
        libffi-devel \
        zlib-devel \
        bzip2-devel \
        readline-devel \
        sqlite-devel \
        xz-devel \
        tk-devel \
        gdbm-devel \
        #libdb-devel \
        #libpcap-devel \
        expat-devel
    
    log_info "基础工具安装完成"
}

# 安装Python 3.8+
install_python() {
    log_step "安装Python 3.8+..."
    
    # 检查Python版本
    if command -v python3 &> /dev/null; then
        local py_version=$(python3 --version | grep -oE '[0-9]+\.[0-9]+')
        local major=$(echo $py_version | cut -d. -f1)
        local minor=$(echo $py_version | cut -d. -f2)
        
        if [[ $major -ge 3 ]] && [[ $minor -ge 8 ]]; then
            log_info "Python $py_version 已安装，跳过安装"
            return
        fi
    fi
    
    # 安装Python 3.8
    dnf install -y python38 python38-devel python38-pip
    
    # 创建软链接
    ln -sf /usr/bin/python3.8 /usr/bin/python3
    ln -sf /usr/bin/pip3.8 /usr/bin/pip3
    
    # 升级pip
    python3 -m pip install --upgrade pip
    
    log_info "Python安装完成: $(python3 --version)"
}

# 安装MySQL 8.0
install_mysql() {
    log_step "安装MySQL 8.0..."
    
    # 检查MySQL是否已安装
    if systemctl is-active --quiet mysqld; then
        log_info "MySQL已安装并运行，跳过安装"
        return
    fi
    
    # 安装MySQL
    dnf install -y @mysql:8.0
    
    # 启动并设置开机自启
    systemctl start mysqld
    systemctl enable mysqld
    
    # 获取临时密码
    local temp_password=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}' | tail -1)
    
    if [[ -n "$temp_password" ]]; then
        log_info "MySQL临时密码: $temp_password"
        log_warn "请手动运行 mysql_secure_installation 来设置MySQL"
    fi
    
    log_info "MySQL安装完成"
}

# 安装Redis
install_redis() {
    log_step "安装Redis..."
    
    # 检查Redis是否已安装
    if systemctl is-active --quiet redis; then
        log_info "Redis已安装并运行，跳过安装"
        return
    fi
    
    # 安装Redis
    dnf install -y redis
    
    # 启动并设置开机自启
    systemctl start redis
    systemctl enable redis
    
    log_info "Redis安装完成"
}

# 创建项目目录和用户
setup_project() {
    log_step "设置项目环境..."
    
    local project_dir="/opt/lottery"
    local user="lottery"
    
    # 创建用户
    if ! id "$user" &>/dev/null; then
        useradd -r -s /bin/false -d $project_dir $user
        log_info "创建用户: $user"
    fi
    
    # 创建项目目录
    mkdir -p $project_dir/{scripts,logs,data,config}
    chown -R $user:$user $project_dir
    
    # 设置环境变量
    echo "export LOTTERY_HOME=$project_dir" > /etc/profile.d/lottery.sh
    chmod +x /etc/profile.d/lottery.sh
    
    log_info "项目环境设置完成: $project_dir"
}

# 安装Python依赖
install_python_deps() {
    log_step "安装Python依赖包..."
    
    # 创建requirements文件
    cat > /tmp/requirements.txt << 'EOF'
requests>=2.28.0
beautifulsoup4>=4.11.0
lxml>=4.9.0
pymysql>=1.0.2
redis>=4.3.0
loguru>=0.6.0
python-dotenv>=0.20.0
pandas>=1.5.0
sqlalchemy>=1.4.0
aiohttp>=3.8.0
fake-useragent>=1.2.0
retrying>=1.3.3
schedule>=1.2.0
click>=8.1.0
pydantic>=1.10.0
httpx>=0.23.0
asyncio>=3.4.3
concurrent-futures>=3.1.1
multiprocessing-logging>=0.3.4
EOF
    
    # 安装依赖
    pip3 install -r /tmp/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
    
    # 清理临时文件
    rm -f /tmp/requirements.txt
    
    log_info "Python依赖安装完成"
}

# 配置MySQL数据库
setup_mysql_database() {
    log_step "配置MySQL数据库..."
    
    # 等待用户设置MySQL密码
    log_warn "请先运行以下命令设置MySQL root密码："
    log_warn "mysql_secure_installation"
    read -p "MySQL密码设置完成后，请输入root密码: " -s mysql_password
    echo
    
    # 创建数据库和用户
    mysql -u root -p"$mysql_password" << 'EOF'
CREATE DATABASE IF NOT EXISTS lottery_api CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'lottery'@'localhost' IDENTIFIED BY 'password123';
GRANT ALL PRIVILEGES ON lottery_api.* TO 'lottery'@'localhost';
FLUSH PRIVILEGES;
EOF
    
    if [[ $? -eq 0 ]]; then
        log_info "数据库配置完成"
        log_info "数据库名: lottery_api"
        log_info "用户名: lottery"
        log_info "密码: password123"
    else
        log_error "数据库配置失败"
    fi
}

# 创建数据库表
create_database_tables() {
    log_step "创建数据库表..."
    
    # 创建表结构SQL
    cat > /tmp/create_tables.sql << 'EOF'
USE lottery_api;

-- 开奖结果表
CREATE TABLE IF NOT EXISTS lottery_results (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    lottery_type VARCHAR(10) NOT NULL COMMENT '彩种类型',
    period VARCHAR(20) NOT NULL COMMENT '期号',
    draw_date DATE NOT NULL COMMENT '开奖日期',
    draw_time DATETIME NULL COMMENT '开奖时间',
    red_numbers JSON NULL COMMENT '红球号码',
    blue_numbers JSON NULL COMMENT '蓝球号码',
    all_numbers JSON NOT NULL COMMENT '所有号码',
    sales_amount DECIMAL(15,2) NULL COMMENT '销售额',
    pool_amount DECIMAL(15,2) NULL COMMENT '奖池金额',
    prize_info JSON NULL COMMENT '奖级信息',
    extra_data JSON NULL COMMENT '额外数据',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uk_lottery_period (lottery_type, period),
    INDEX idx_lottery_type (lottery_type),
    INDEX idx_draw_date (draw_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='开奖结果表';

-- 奖级详情表
CREATE TABLE IF NOT EXISTS lottery_prizegrades (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    lottery_type VARCHAR(10) NOT NULL COMMENT '彩种类型',
    period VARCHAR(20) NOT NULL COMMENT '期号',
    prize_type INT NOT NULL COMMENT '奖级类型',
    prize_winners INT NOT NULL DEFAULT 0 COMMENT '中奖注数',
    prize_amount DECIMAL(15,2) NOT NULL DEFAULT 0 COMMENT '单注奖金',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uk_lottery_prize (lottery_type, period, prize_type),
    INDEX idx_lottery_type (lottery_type),
    INDEX idx_period (period)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='奖级详情表';

-- 一等奖详情表
CREATE TABLE IF NOT EXISTS lottery_prize_details (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    lottery_type VARCHAR(10) NOT NULL COMMENT '彩种类型',
    period VARCHAR(20) NOT NULL COMMENT '期号',
    draw_date DATE NULL COMMENT '开奖日期',
    total_first_prize_winners INT NULL COMMENT '一等奖总中奖注数',
    total_first_prize_amount DECIMAL(15,2) NULL COMMENT '一等奖总奖金',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uk_lottery_period (lottery_type, period),
    INDEX idx_lottery_type (lottery_type),
    INDEX idx_draw_date (draw_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='一等奖详情表';

-- 省份中奖表
CREATE TABLE IF NOT EXISTS lottery_province_prizes (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    lottery_type VARCHAR(10) NOT NULL COMMENT '彩种类型',
    period VARCHAR(20) NOT NULL COMMENT '期号',
    province_name VARCHAR(50) NOT NULL COMMENT '省份名称',
    province_code VARCHAR(10) NULL COMMENT '省份代码',
    first_prize_winners INT NULL DEFAULT 0 COMMENT '一等奖中奖注数',
    first_prize_amount DECIMAL(15,2) NULL COMMENT '一等奖奖金',
    station_info TEXT NULL COMMENT '投注站信息',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uk_province_prize (lottery_type, period, province_name),
    INDEX idx_lottery_type (lottery_type),
    INDEX idx_period (period),
    INDEX idx_province (province_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='省份中奖表';
EOF
    
    # 执行SQL
    mysql -u lottery -ppassword123 < /tmp/create_tables.sql
    
    if [[ $? -eq 0 ]]; then
        log_info "数据库表创建完成"
    else
        log_error "数据库表创建失败"
    fi
    
    # 清理临时文件
    rm -f /tmp/create_tables.sql
}

# 配置防火墙
setup_firewall() {
    log_step "配置防火墙..."
    
    # 启动防火墙
    systemctl start firewalld
    systemctl enable firewalld
    
    # 开放必要端口
    firewall-cmd --permanent --add-port=3306/tcp  # MySQL
    firewall-cmd --permanent --add-port=6379/tcp  # Redis
    firewall-cmd --permanent --add-port=9501/tcp  # API服务
    
    # 重新加载防火墙
    firewall-cmd --reload
    
    log_info "防火墙配置完成"
}

# 创建配置文件
create_config_files() {
    log_step "创建配置文件..."
    
    local project_dir="/opt/lottery"
    
    # 创建环境配置文件
    cat > $project_dir/config/.env << 'EOF'
# 数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_USER=lottery
DB_PASSWORD=password123
DB_NAME=lottery_api

# Redis配置
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0

# API配置
JISU_API_KEY=9aa6d92f8d70a0a9
API_BASE_URL=https://api.jisuapi.com/caipiao

# 日志配置
LOG_LEVEL=INFO
LOG_DIR=/opt/lottery/logs
EOF
    
    # 设置权限
    chown lottery:lottery $project_dir/config/.env
    chmod 600 $project_dir/config/.env
    
    log_info "配置文件创建完成: $project_dir/config/.env"
}

# 创建systemd服务文件
create_systemd_services() {
    log_step "创建系统服务..."
    
    # 历史数据爬虫服务
    cat > /etc/systemd/system/lottery-history-crawler.service << 'EOF'
[Unit]
Description=Lottery History Data Crawler
After=network.target mysql.service redis.service

[Service]
Type=oneshot
User=lottery
Group=lottery
WorkingDirectory=/opt/lottery/scripts
Environment=PYTHONPATH=/opt/lottery
ExecStart=/usr/bin/python3 run_crawler.py --mode history-smart --count 100
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF
    
    # 当前期数据爬虫服务
    cat > /etc/systemd/system/lottery-current-crawler.service << 'EOF'
[Unit]
Description=Lottery Current Data Crawler
After=network.target mysql.service redis.service

[Service]
Type=oneshot
User=lottery
Group=lottery
WorkingDirectory=/opt/lottery/scripts
Environment=PYTHONPATH=/opt/lottery
ExecStart=/usr/bin/python3 run_crawler.py --mode latest
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF
    
    # 定时任务服务
    cat > /etc/systemd/system/lottery-current-crawler.timer << 'EOF'
[Unit]
Description=Run lottery current crawler every hour
Requires=lottery-current-crawler.service

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target
EOF
    
    # 重新加载systemd
    systemctl daemon-reload
    
    # 启用定时器
    systemctl enable lottery-current-crawler.timer
    systemctl start lottery-current-crawler.timer
    
    log_info "系统服务创建完成"
}

# 设置日志轮转
setup_log_rotation() {
    log_step "设置日志轮转..."
    
    cat > /etc/logrotate.d/lottery << 'EOF'
/opt/lottery/logs/*.log {
    daily
    missingok
    rotate 30
    compress
    notifempty
    create 644 lottery lottery
    postrotate
        systemctl reload lottery-current-crawler.timer > /dev/null 2>&1 || true
    endscript
}
EOF
    
    log_info "日志轮转设置完成"
}

# 设置cron定时任务（备用）
setup_cron_jobs() {
    log_step "设置定时任务..."
    
    # 为lottery用户添加定时任务
    cat > /tmp/lottery_crontab << 'EOF'
# 每小时抓取当前期数据
0 * * * * cd /opt/lottery/scripts && /usr/bin/python3 run_crawler.py --mode latest >> /opt/lottery/logs/cron.log 2>&1

# 每天凌晨2点抓取历史数据
0 2 * * * cd /opt/lottery/scripts && /usr/bin/python3 run_crawler.py --mode history-smart --count 10 >> /opt/lottery/logs/cron.log 2>&1

# 每周日凌晨3点清理旧日志
0 3 * * 0 find /opt/lottery/logs -name "*.log" -mtime +30 -delete
EOF
    
    # 安装定时任务
    sudo -u lottery crontab /tmp/lottery_crontab
    
    # 清理临时文件
    rm -f /tmp/lottery_crontab
    
    log_info "定时任务设置完成"
}

# 最终检查
final_check() {
    log_step "进行最终检查..."
    
    # 检查服务状态
    local services=("mysqld" "redis" "firewalld")
    for service in "${services[@]}"; do
        if systemctl is-active --quiet $service; then
            log_info "$service 服务运行正常"
        else
            log_warn "$service 服务未运行"
        fi
    done
    
    # 检查Python环境
    if python3 -c "import requests, pymysql, redis, loguru" 2>/dev/null; then
        log_info "Python依赖检查通过"
    else
        log_warn "Python依赖检查失败"
    fi
    
    # 检查数据库连接
    if mysql -u lottery -ppassword123 -e "USE lottery_api; SHOW TABLES;" >/dev/null 2>&1; then
        log_info "数据库连接正常"
    else
        log_warn "数据库连接失败"
    fi
    
    log_info "系统检查完成"
}

# 显示安装结果
show_install_result() {
    log_step "安装完成！"
    
    echo
    echo "=================================="
    echo "    彩票爬虫系统安装完成"
    echo "=================================="
    echo
    echo "项目目录: /opt/lottery"
    echo "配置文件: /opt/lottery/config/.env"
    echo "日志目录: /opt/lottery/logs"
    echo "脚本目录: /opt/lottery/scripts"
    echo
    echo "数据库信息:"
    echo "  主机: localhost"
    echo "  端口: 3306"
    echo "  数据库: lottery_api"
    echo "  用户名: lottery"
    echo "  密码: password123"
    echo
    echo "Redis信息:"
    echo "  主机: localhost"
    echo "  端口: 6379"
    echo
    echo "系统服务:"
    echo "  历史数据爬虫: lottery-history-crawler.service"
    echo "  当前期爬虫: lottery-current-crawler.service"
    echo "  定时器: lottery-current-crawler.timer"
    echo
    echo "手动运行命令:"
    echo "  抓取历史数据: cd /opt/lottery/scripts && python3 lottery_history_crawler.py --all"
    echo "  抓取当前期: cd /opt/lottery/scripts && python3 lottery_current_crawler.py --all"
    echo
    echo "查看服务状态:"
    echo "  systemctl status lottery-current-crawler.timer"
    echo "  systemctl status mysqld"
    echo "  systemctl status redis"
    echo
    echo "查看日志:"
    echo "  tail -f /opt/lottery/logs/*.log"
    echo "  journalctl -u lottery-current-crawler.service"
    echo
    log_info "请复制爬虫脚本到 /opt/lottery/scripts/ 目录后开始使用"
}

# 主函数
main() {
    log_info "开始安装CentOS 8 Python彩票爬虫系统..."
    
    check_root
    check_centos_version
    
    update_system
    install_basic_tools
    install_python
    install_mysql
    install_redis
    setup_project
    install_python_deps
    setup_mysql_database
    create_database_tables
    setup_firewall
    create_config_files
    create_systemd_services
    setup_log_rotation
    setup_cron_jobs
    final_check
    show_install_result
    
    log_info "安装脚本执行完成！"
}

# 执行主函数
main "$@"
